#include "documentsaver.h"
#include <QFile>
#include "../document.h"
#include "../gameobjects/graphicsobject.h"
#include "../gameobjects/animation.h"
#include "../gameobjects/texture.h"
#include "../physics/collisionshapes.h"

DocumentSaver::DocumentSaver(QObject *parent) :
    DocumentSerializer(parent)
{
}

void DocumentSaver::saveGraphicsObject(QPointer<GraphicsObject> gobject, QDataStream &out)
{
    int guid = gobject->guid();
    QString id = gobject->id();

    out << (int)guid;
    out << id;

    if(gobject->hasAnimations())
    {
        out << (bool)true;

        // save animation info
    }
    else
    {
        out << (bool)false;

        if(!gobject->hasTexture())
        {
            out << (bool)false;
            return;
        }

        out << (bool)true;

        // save texture info
        saveTexture(gobject->texture(), out);

        int numColShapes = gobject->collisionShapes().size();
        out << (int)numColShapes;

        if(numColShapes)
        {
            foreach(QPointer<CollisionShape> shape, gobject->collisionShapes())
            {
                saveCollisionShape(shape, out);
            }
        }
    }
}

void DocumentSaver::saveTexture(QPointer<Texture> texture, QDataStream &out)
{
    int parentGuid = texture->parentObject() ? texture->parentObject()->guid() : -1;

    out << (int)texture->guid();
    out << texture->id();
    out << (int)parentGuid;
    out << texture->fileName();
}

void DocumentSaver::saveAnimation(QPointer<Animation> gobject, QDataStream &out)
{
}

void DocumentSaver::saveAnimationFrame(const AnimationFrame &frame, QDataStream &out)
{
}

void DocumentSaver::saveCollisionShape(QPointer<CollisionShape> cshape, QDataStream& out)
{
    QPointer<AbstractObject> owner = cshape->shapeOwner();

    out << (int)owner->guid();

    if(QPointer<CollisionBox> rectangle = qobject_cast<CollisionBox*>(cshape))
    {
        // type
        out << (int)0;
        out << rectangle->rect();
    }
    else if(QPointer<CollisionCircle> circle = qobject_cast<CollisionCircle*>(cshape))
    {
        // type
        out << (int)1;
        out << circle->center();
        out << (float)circle->radius();
    }
    else if(QPointer<CollisionPoly> polygon = qobject_cast<CollisionPoly*>(cshape))
    {
        // type
        out << (int)2;
        out << polygon->poly();
    }
}

bool DocumentSaver::serialize(const QString &filePath, QPointer<Document> document)
{
    QFile file(filePath);

    if(!file.open(QIODevice::WriteOnly))
    {
        return false;
    }

    QDataStream out(&file);

    QList<QPointer<GraphicsObject> > gobjects = document->graphicsObjects();

    if(int count = gobjects.size())
    {
        out << (int)count;

        foreach(QPointer<GraphicsObject> go, gobjects)
        {
            saveGraphicsObject(go, out);
        }
    }

    file.close();

    return true;
}
